package com.acumenvn.pent.GameServices;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Disposable;
import com.acumenvn.pent.GameServices.SoundManager.PenSound;
import com.acumenvn.pent.Utils.LRUCache.CacheEntryRemovedListener;
import com.acumenvn.pent.Utils.LRUCache;

public class SoundManager implements Disposable, CacheEntryRemovedListener<PenSound, Sound> {

	public enum PenSound {
		
		private final String _fileName;
		
		private PenSound(String fileName) {
			this._fileName = fileName;
		}
		
		public String getFileName() {
			return this._fileName;
		}
	}
	
	/**
     * The sound cache.
     */
    private final LRUCache<PenSound,Sound> _soundCache;
	
	// volume
	
	private float _soundVolume = 1f;
	
	public void setVolume(float val) {
		if(val > 1 || val < 0) {
			throw new IllegalArgumentException( "The volume must be inside the range: [0,1]" );
			return;
		}
		this._soundVolume = val;
	}
	
	private Boolean _soundEnabled = true;
	
	public void setSoundEnabled(Boolean on) {
		this._soundEnabled = on;
	}
	
	// Constructor
	
	public SoundManager() {
		// TODO Auto-generated constructor stub
		_soundCache = new LRUCache<SoundManager.PenSound,Sound>( 10 );
        _soundCache.setEntryRemovedListener( this );
	} 
	
	// play sound
	public void playSound(PenSound p) {
		// check if sound is enable
		if(!this._soundEnabled) {
			return;
		}
		
		// try and get the sound from the cache
		Sound soundToPlay = this._soundCache.get(p);
		if(soundToPlay == null) {
			FileHandle soundFile = Gdx.files.internal(p.getFileName());
			soundToPlay = Gdx.audio.newSound(soundFile);
			this._soundCache.add(p, soundToPlay);
		}
		
		// play the sound
		soundToPlay.play(_soundVolume);
	}
	
	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		for (Sound s : this._soundCache.retrieveAll()) {
			s.stop();
			s.dispose();
		}
		
		
	}

	@Override
	public void notifyEntryRemoved(PenSound key, Sound value) {
		// TODO Auto-generated method stub
		value.dispose();
	}

}
